<template>
  <div class="salesForcast">
    <el-card v-show="isTrainPage">
      <div class="block">
        <h3 class="demonstration">
          <i class="el-icon-paperclip"></i> 请选择月份区间
        </h3>
        <el-date-picker
          v-model="dateValue"
          type="monthrange"
          align="right"
          unlink-panels
          range-separator="至"
          start-placeholder="开始月份"
          end-placeholder="结束月份"
          :picker-options="pickerOptions"
          @blur="fillDate"
        >
        </el-date-picker>
        <el-button
          class="ml__20"
          @click="
            dateValue = '';
            form.salesData = [];
            form.yearAndMonth = [];
          "
          >清空</el-button
        >
      </div>
      <div class="block" v-if="form.salesData.length > 1">
        <h3 class="demonstration">
          <i class="el-icon-edit-outline"></i> 请填写数据
        </h3>
        <div class="flex__content__between">
          <el-card style="width:72%;">
            <h3 class="mb__20">汽车信息</h3>
            <el-input
              placeholder="请输入内容"
              v-model="form.series"
              style="width:98%;"
              class="mb__20"
              size="large"
            >
              <template slot="prepend">汽车名称:</template>
            </el-input>
            <h3 style="margin:20px 0">历史销量</h3>
            <div v-for="(item, index) in form.yearAndMonth" :key="item">
              <span
                style="float:left;margin:10px 0 0 1%;
                    color: #8492a6;
                    font-size: 17px;
                    font-weight: bold;"
                class="span"
                ><i class="el-icon-time"></i> {{ item }}</span
              >
              <span
                style="float:right;margin:6px 0 0 1%;
                    color: #8492a6;
                    font-size: 16px;
                    font-weight: bold;"
                class="span"
                >单位/万辆</span
              >
              <el-slider
                v-model="form.salesData[index]"
                show-input
                :max="maxValue"
                :step="0.1"
                style="width:72%;margin-left:18%"
                input-size="small"
              ></el-slider>
              <el-divider></el-divider>
            </div>
          </el-card>
          <el-card style="width:26%;" class="optionBtn">
            <h3 class="mb__20">
              <i class="el-icon-collection-tag"></i> 随机数据生成
            </h3>
            <div class="flex__content__between">
              <el-button @click="randomData(false)" type="small">随机生成数据</el-button>
              <el-button @click="randomData(true)" type="small">填充剩余数据</el-button>
            </div>
            <el-divider><i class="el-icon-setting"></i></el-divider>
            <h3 class="my__20">
              <i class="el-icon-collection-tag"></i> SARIMA模型
            </h3>
            <div v-loading="isRollLoading">
              <h4 class="mb__10">滚动预测<small>（训练集比例）</small></h4>
              <el-input
                placeholder="请输入内容"
                v-model="ratio"
                class="input-with-select"
              >
                <el-button slot="append" @click="onSubmit">预测</el-button>
              </el-input>
            </div>
            <div class="mt__20" v-loading="isTradLoading">
              <h4 class="mb__10">传统预测<small>（未来n个月）</small></h4>
              <el-input
                placeholder="请输入内容"
                v-model.number="forcastMonth"
                class="input-with-select"
              >
                <el-button slot="append" @click="onSubmitTradition"
                  >预测</el-button
                >
              </el-input>
            </div>
          </el-card>
        </div>
      </div>
    </el-card>
    <el-card v-show="!isTrainPage">
      <el-page-header @back="goBack" content="详情页面"></el-page-header>
      <SalesCharts
        :chart-data="rollPredResObj"
        v-if="rollPredResObj.seriesId != undefined"
        :xAxis="xAxis"
      />
      <div
        style="display:flex;justify-content:space-around;"
        v-if="rollPredResObj.seriesId != undefined"
      >
        <h3>
          滚动预测 <i>R²</i> 得分：<span style="color:#F72C5B">{{
            rollPredResObj.rollScore
          }}</span>
        </h3>
        <h3>
          超参数优化AIC最小值：<span style="color:#F72C5B">{{
            rollPredResObj.aic
          }}</span>
        </h3>
        <h3>
          SARIMA参数：<span style="color:#F72C5B"
            >{{ rollPredResObj.pdq }} × {{ rollPredResObj.pdq_x_PDQs }}</span
          >
        </h3>
        <h3>
          传统预测 <i>R²</i> 得分：<span>{{
            rollPredResObj.traditionScore
          }}</span>
        </h3>
      </div>
      <TradSalesCharts
        :chart-data="traditionPredResObj"
        v-if="traditionPredResObj.seriesId != undefined"
        :xAxis="xAxis"
      />
      <div
        style="display:flex;justify-content:space-around;"
        v-if="traditionPredResObj.seriesId != undefined"
      >
        <h3>
          超参数优化AIC最小值：<span style="color:#F72C5B">{{
            traditionPredResObj.aic
          }}</span>
        </h3>
        <h3>
          SARIMA参数：<span style="color:#F72C5B"
            >{{ traditionPredResObj.pdq }} ×
            {{ traditionPredResObj.pdq_x_PDQs }}</span
          >
        </h3>
      </div>
    </el-card>
  </div>
</template>
<script>
import SalesCharts from "@/components/SalesCharts";
import TradSalesCharts from "@/components/TradSalesCharts";
import { getXDate } from "@/utils/predict.js";
import {
  predictSaleOnline,
  predictSaleOnlineTradition,
} from "@/api/salesPredict";
export default {
  data() {
    return {
      // 日期选择选项
      pickerOptions: {
        shortcuts: [
          {
            text: "最近一年半",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setMonth(start.getMonth() - 17);
              picker.$emit("pick", [start, end]);
            },
          },
          {
            text: "最近两年",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setMonth(start.getMonth() - 23);
              picker.$emit("pick", [start, end]);
            },
          },
          {
            text: "最近三年",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setMonth(start.getMonth() - 35);
              picker.$emit("pick", [start, end]);
            },
          },
          {
            text: "最近64月",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setMonth(start.getMonth() - 63);
              picker.$emit("pick", [start, end]);
            },
          },
        ],
      },
      // 日期间隔
      dateValue: [],
      // 表单提交数据
      form: {
        yearAndMonth: [],
        salesData: [],
        series: "汽车甲品牌",
        seriesId: "s10086",
      },
      // 最大值
      maxValue: 10,
      // 在线预测训练数据比例
      ratio: 0.75,
      // 未来几个月
      forcastMonth: 6,
      // 是否滚动预测中
      isRollLoading: false,
      // 是否传统预测中
      isTradLoading: false,
      // 是否为当前数据选择训练页
      isTrainPage: true,
      // 滚动预测结果
      rollPredResObj: {},
      // 传统预测结果
      traditionPredResObj: {},
      // X轴
      xAxis: [],
    };
  },
  components: {
    SalesCharts,
    TradSalesCharts,
  },
  created() {
    const end = new Date();
    const start = new Date();
    start.setMonth(start.getMonth() - 35);
    this.dateValue = [start, end];
    this.fillDate();
  },
  methods: {
    // 生成日期
    fillDate() {
      let beginDate = this.dateValue[0];
      let plusMonth =
        this.dateValue[1].getFullYear() * 12 +
        this.dateValue[1].getMonth() +
        1 -
        (this.dateValue[0].getFullYear() * 12 +
          this.dateValue[0].getMonth() +
          1) +
        1;

      let result = [];
      beginDate = new Date(beginDate);
      console.log(beginDate, plusMonth);
      let { year, month } = {
        year: beginDate.getFullYear(),
        month: beginDate.getMonth() + 1,
      };

      for (let i = 1; i <= plusMonth; i++) {
        result.push(
          month % 12 == 0
            ? `${year++}/${(month++ % 12) + 12}/1`
            : `${year}/${month++ % 12}/1`
        );
      }
      this.form.yearAndMonth = result;
      this.form.salesData = Array(result.length).fill(0);
    },
    // 随机生成数据
    randomData(flag) {
      this.form.salesData.forEach((item, index) => {
        let randomValue;
        if (index % 6 <= 2) {
          randomValue = Math.random() + 1;
        } else {
          randomValue = Math.random();
        }
        if (flag && item == 0) {
          this.$set(
            this.form.salesData,
            index,
            parseFloat(randomValue.toFixed(2))
          );
        } else if (!flag) {
          this.$set(
            this.form.salesData,
            index,
            parseFloat(randomValue.toFixed(2))
          );
        }
      });
    },
    // 提交训练
    onSubmit() {
      this.traditionPredResObj = {};
      this.isRollLoading = true;
      predictSaleOnline(this.form, this.ratio).then((res) => {
        if (res.data.code == 200) {
          this.isTrainPage = false;
          /* * * * * *
           *  Action *
           * * * * * */

          let resObj = res.data.data;
          // xAxis
          this.xAxis = this.form.yearAndMonth;
          // 进行序列填充
          let unshowData = Array(
            this.form.yearAndMonth.length - resObj.rollPredRes.length
          ).fill("-");
          resObj.rollPredRes.unshift(unshowData);
          resObj.traditionPredRes.unshift(unshowData);
          // 拉平
          resObj.rollPredRes = resObj.rollPredRes.flat();
          resObj.traditionPredRes = resObj.traditionPredRes.flat();
          this.rollPredResObj = resObj;
        } else {
          this.$message.error("滚动预测失败，请重新调整！");
        }

        this.isRollLoading = false;
      });
    },
    // 传统预测训练
    onSubmitTradition() {
      this.rollPredResObj = {};
      this.isTradLoading = true;
      predictSaleOnlineTradition(this.form, this.forcastMonth).then((res) => {
        if (res.data.code == 200) {
          this.isTrainPage = false;
          // Action
          let resObj = res.data.data;
          let fullLength = this.form.yearAndMonth.length + this.forcastMonth;
          // xAxis
          this.xAxis = getXDate(this.dateValue[0], fullLength);
          // 进行序列填充
          resObj.salesData.push(resObj.traditionPredRes[0]);
          resObj.salesData.push(
            Array(this.form.yearAndMonth.length - 1).fill("-")
          );
          resObj.traditionPredRes.unshift(
            Array(fullLength - resObj.traditionPredRes.length).fill("-")
          );
          // 拉平
          resObj.salesData = resObj.salesData.flat();
          resObj.traditionPredRes = resObj.traditionPredRes.flat();
          this.traditionPredResObj = resObj;
        } else {
          this.$message.error("传统预测失败，请重新调整！");
        }

        this.isTradLoading = false;
      });
    },
    // 回到训练页
    goBack() {
      this.isTrainPage = true;
    },
  },
};
</script>

<style lang="scss">
.ml__20 {
  margin-left: 20px;
}
.mb__20 {
  margin-bottom: 20px;
}
.my__20 {
  margin: 20px 0;
}
.ml__10 {
  margin-left: 10px;
}
.mb__10 {
  margin-bottom: 10px;
}
.my__10 {
  margin: 10px 0;
}
.flex__content__between {
  display: flex;
  justify-content: space-between;
}
.optionBtn {
  div {
    margin-bottom: 10px;
  }
}
.block {
  margin-bottom: 20px;
}
</style>
<style>
/* 修改element-ui 样式 */
.demonstration {
  margin-bottom: 16px;
}
.el-range-separator {
  width: 20% !important;
}
.el-picker-panel {
  margin-left: 21vw;
}

.el-slider__runway.show-input {
  margin-right: 320px;
}
.el-slider__input {
  width: 300px;
}
</style>
